(function() {
    var Yz = window.Yz = function() {};

    /**
     *  make the function console.log available everywhere
     *
     */
    if (typeof console != "undefined") {
        console.log("Yz init");
    } else {
        window.console = { log: function() {} };
    }

    Yz.webPrefix = "/";

    Yz.loadedClasses = {};

    Yz.block = function()
    {
        console.log("block");
        document.body.style.cursor = "wait";
    }

    Yz.unblock = function()
    {
        console.log("unblock");
        document.body.style.cursor = "";
    }

    Yz.loadClass = function(className, callback)
    {
        var loadedClass;
        if (className in Yz.loadedClasses) {
            loadedClass = Yz.loadedClasses[className];
            callback && callback();
        } else {
            try {
                Yz.fetchScript(
                    Yz.webPrefix + "www/Yz/js/" + className + ".js",
                    function() {
                        console.log("Loaded class: "+className);
                        callback && callback();
                    }
                );
            } catch (ex) {
                Yz.Alert("Failed to load plugin " + plugin + ": " + ex);
                throw "Failed to load plugin " + plugin + ": " + ex;
                //return false;
            }
        }
        return loadedClass;
    }

    /**
     *  `require' jQuery
     *
     */
    Yz.jQuery = Yz.jquery = function(callback)
    {
        try {
            Yz.fetchScript(
                Yz.webPrefix + "www/jquery/js/jquery.js",
                function() {
                    console.log("Loaded jQuery");
                    callback && callback();
                    Yz.jQuery = Yz.jquery = function(callback)
                    {
                        console.log("jQuery already loaded");
                        callback && callback();
                    };
                }
            );
        } catch (ex) {
            throw "Failed to load jQuery: " + ex;
        }
        return Yz;
    }

    /**
     *  `require' jQuery
     *
     */
    Yz.jQueryUI = Yz.jqueryui = function(callback)
    {
        Yz.jQuery( function() {
            Yz.fetchStyleSheet(
                Yz.webPrefix + "www/jquery/css/jquery-ui.css"
            );
            try {
                Yz.fetchScript(
                    Yz.webPrefix + "www/jquery/js/jquery-ui.js",
                    function() {
                        console.log("Loaded jQuery UI");
                        callback && callback();
                        Yz.jQueryUI = Yz.jqueryui = function(callback)
                        {
                            console.log("jQuery UI already loaded");
                            callback && callback();
                        };
                    }
                );
            } catch (ex) {
                throw "Failed to load jQuery UI: " + ex;
            }
        });
        return Yz;
    }


    Yz.translate =  function(message)
    {
        return message;
    }

    /**
     *  alert user with a message using a modal dialog
     *
     */
    Yz.Alert = function(message, title)
    {
        var dlg = Yz.Alert.dialog;
        if (! dlg) {
            dlg = document.createElement("DIV");
            dlg.className = "yz-dialog";
            var buttons = {};
            buttons["Cancel"] = function() { $(this).dialog("close"); }
            Yz.Alert.dialog = dlg;
            Yz.Alert.buttons = buttons;
        }
        if (! title) {
            title = Yz.translate("Alert");
        }
        $(dlg)
            .text(message)
            .dialog({
                modal: true,
                title: title,
                buttons: Yz.Alert.buttons
            });
        return Yz;
    }
    /**
     *  notify user with a message using a non-blocking UI element
     *
     */
    Yz.Notify = function(message)
    {
        alert(message);
        return Yz;
    }


    Yz.fetchScript = function(script, onsuccess, onerror)
    {
        Yz.block();
        var plugin = document.createElement("SCRIPT");
        plugin.setAttribute('src', script);
        plugin.onload = function()
        {
            onsuccess && onsuccess();
            Yz.unblock();
        }
        plugin.onerror = function()
        {
            onerror && onerror();
            Yz.unblock();
        }
        document.getElementsByTagName("HEAD")[0].appendChild(plugin);
        return Yz;
    }

    Yz.fetchStyleSheet = function(href, onsuccess, onerror)
    {
        Yz.block();
        var plugin = document.createElement("LINK");
        plugin.href = href;
        plugin.setAttribute('rel', 'stylesheet');
        plugin.setAttribute('type', 'text/css');
        plugin.onload = function()
        {
            onsuccess && onsuccess();
            Yz.unblock();
        }
        plugin.onerror = function()
        {
            onerror && onerror();
            Yz.unblock();
        }
        document.getElementsByTagName("HEAD")[0].appendChild(plugin);
        return Yz;
    }


})();
